home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / video / xevil-1.000 / xevil-1 / xshow.C < prev    next >
C/C++ Source or Header  |  1995-04-16  |  7KB  |  327 lines

  1. // Program to display an image with the appropriate mask.
  2. // Steve Hardt 2/7/93
  3. // Modified 5/4/94 to work without Motif.
  4.  
  5. // Include Files
  6. extern "C"
  7. {
  8. // C includes
  9. #include <stdio.h>
  10. #include <stdlib.h> // For exit().
  11. #include <time.h>
  12.  
  13. // Unix includes
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16. #include <unistd.h>
  17.  
  18. // X includes
  19. #include <X11/X.h>
  20. #include <X11/Xlib.h>
  21. #include <X11/Xos.h>
  22. #include <X11/Xutil.h>
  23. #include <X11/keysym.h>
  24. }
  25. #include <assert.h>
  26. #include <iostream.h>
  27.  
  28.  
  29. // Defines
  30. #define FILENAME_LENGTH 100
  31. #define TIME_UNIT 1 // sec
  32. #define INITIAL_WIDTH 1
  33. #define INITIAL_HEIGHT 1
  34.  
  35.  
  36.  
  37. class State {
  38.  public:
  39.   State(int,char **);
  40.   Display *getDpy() {return dpy;}
  41.   int canDraw() {return pixmap != 0;}
  42.   void reloadImage();
  43.   void checkQuit(XEvent &);
  44.   void checkFiles();
  45.   void draw();
  46.  
  47.  
  48.  private:
  49.   Display *dpy;
  50.   Window drawing;
  51.   Screen *scr_ptr;
  52.   int scr_num;
  53.   Window root;
  54.   int depth;
  55.   Colormap cmap;
  56.   GC gc;
  57.   Pixmap pixmap,mask; // 0 if not yet defined.
  58.   int pixmapWidth,pixmapHeight;
  59.  
  60.   char pixmapName[FILENAME_LENGTH];
  61.   char maskSet;
  62.   char maskName[FILENAME_LENGTH];
  63.  
  64.   time_t pixmapTime;
  65.   time_t maskTime;
  66. };
  67.  
  68.  
  69.  
  70. // Functions
  71. State::State(int argc,char **argv)
  72. {
  73.   // Parse command line.
  74.   if (argc < 4)
  75.     {
  76.       cout << "Usage: " << argv[0] << " <foreground> <background> <pixmap> " 
  77.     << "[mask]" << endl;
  78.       exit (-1);
  79.     }
  80.  
  81.   strcpy(pixmapName,argv[3]);
  82.   if (argc >= 5)
  83.     {
  84.       maskSet = True;
  85.       strcpy(maskName,argv[4]);
  86.     }
  87.   else
  88.     maskSet = False;
  89.  
  90.   
  91.   // Open display, create window.
  92.   dpy = XOpenDisplay(NULL);
  93.  
  94.   if (! dpy)
  95.     cout << "Could not open display." << endl;
  96.  
  97.   scr_ptr = DefaultScreenOfDisplay(dpy);
  98.   scr_num = DefaultScreen(dpy);
  99.   root = RootWindowOfScreen(scr_ptr);
  100.   depth = DefaultDepthOfScreen(scr_ptr);
  101.   cmap = DefaultColormap(dpy,scr_num);
  102.  
  103.   drawing = XCreateSimpleWindow(dpy, root, 
  104.                 0, 0, INITIAL_WIDTH, INITIAL_HEIGHT, 
  105.                 0, 
  106.                 BlackPixel(dpy,scr_num), 
  107.                 WhitePixel(dpy,scr_num));
  108.  
  109.  
  110.   XSizeHints size_hints;
  111.   size_hints.flags = PPosition | PSize ;
  112.  
  113.   XTextProperty windowName, iconName;
  114.   char *window_name = "xshow";  // Will appear on window.
  115.   char *icon_name = "xshow";
  116.   assert(XStringListToTextProperty(&window_name,1,&windowName));
  117.   assert(XStringListToTextProperty(&icon_name,1,&iconName)); 
  118.   
  119.   XWMHints wm_hints;
  120.   wm_hints.initial_state = NormalState;
  121.   wm_hints.input = True;
  122.   wm_hints.flags = StateHint | InputHint;
  123.  
  124.   XClassHint class_hints;
  125.   class_hints.res_name = argv[0];
  126.   class_hints.res_class = "XShow";
  127.  
  128.   XSetWMProperties(dpy,drawing,&windowName,&iconName,
  129.            argv,argc,&size_hints,&wm_hints,&class_hints);
  130.  
  131.   XSelectInput(dpy,drawing,ExposureMask | KeyPressMask | ButtonPressMask);
  132.  
  133.   XMapWindow(dpy,drawing);
  134.   
  135.  
  136.   // Create GC.
  137.   XColor actual,database;
  138.   XGCValues values;
  139.   if (! XAllocNamedColor(dpy,cmap,argv[1],&actual,&database))
  140.     {
  141.       cout << "Could not allocate foreground color" << endl;
  142.       exit (-1);
  143.     }
  144.   values.foreground = actual.pixel;
  145.  
  146.   if (! XAllocNamedColor(dpy,cmap,argv[2],&actual,&database))
  147.     {
  148.       cout << "Could not allocate background color" << endl;
  149.       exit (-1);
  150.     }
  151.   values.background = actual.pixel;
  152.   gc = XCreateGC(dpy,root,GCForeground|GCBackground,&values);
  153.  
  154.   // Set previous times for pixmap and mask.
  155.   struct stat pixmapStat;
  156.   stat(pixmapName,&pixmapStat);
  157.   pixmapTime = pixmapStat.st_mtime;
  158.  
  159.   if (maskSet)
  160.     {
  161.       struct stat maskStat;
  162.       stat(maskName,&maskStat);
  163.       maskTime = maskStat.st_mtime;
  164.     }
  165.  
  166.   pixmap = mask = 0;
  167. }
  168.  
  169.  
  170.  
  171. void State::reloadImage()
  172. {
  173.   Pixmap pixmapTmp,maskTmp;
  174.   unsigned int pixmapWidthTmp,pixmapHeightTmp,
  175.   maskWidthTmp,maskHeightTmp;
  176.   int x_hot,y_hot;
  177.  
  178.   if (XReadBitmapFile(dpy,root,pixmapName,
  179.               &pixmapWidthTmp,&pixmapHeightTmp,&pixmapTmp,&x_hot,&y_hot) != 
  180.       BitmapSuccess)
  181.     {
  182.       cout << pixmapName << ":  failed to read pixmap." << endl;
  183.       return;
  184.     }
  185.  
  186.   if (maskSet)
  187.     {
  188.       if (XReadBitmapFile(dpy,root,maskName,
  189.               &maskWidthTmp,&maskHeightTmp,&maskTmp,&x_hot,&y_hot) != 
  190.       BitmapSuccess)
  191.     {
  192.       XFreePixmap(dpy,pixmapTmp);
  193.       cout << maskName << ":  failed to read mask." << endl;
  194.       return;
  195.     }
  196.  
  197.       if ((pixmapWidthTmp != maskWidthTmp) || (pixmapHeightTmp != maskHeightTmp))
  198.     {
  199.       XFreePixmap(dpy,pixmapTmp);
  200.       XFreePixmap(dpy,maskTmp);
  201.       cout << pixmapName << ":  pixmap and mask have different sizes." 
  202.         << endl;
  203.       return;
  204.     }
  205.     }
  206.  
  207.  
  208.   // Replace old pixmap and mask with new.
  209.   if (pixmap)
  210.     XFreePixmap(dpy,pixmap);
  211.   pixmap = pixmapTmp;
  212.   pixmapWidth = pixmapWidthTmp;
  213.   pixmapHeight = pixmapHeightTmp;
  214.   if (maskSet)
  215.     {
  216.       if (mask)
  217.     XFreePixmap(dpy,mask);
  218.       mask = maskTmp;
  219.     }
  220.  
  221.   XWindowChanges changes;
  222.   changes.width = pixmapWidth;
  223.   changes.height = pixmapHeight;
  224.   XReconfigureWMWindow(dpy,drawing,scr_num,CWWidth | CWHeight,&changes);
  225.   
  226.   if (maskSet)
  227.     cout << pixmapName << " with mask " << maskName << " reloaded." << endl;
  228.   else
  229.     cout << pixmapName << " reloaded." << endl;
  230.  
  231.   draw();
  232. }
  233.  
  234.  
  235.  
  236. void State::checkQuit(XEvent &event)
  237. {
  238.   if (event.type == KeyPress)
  239.     {
  240.       KeySym keysym;
  241.       XLookupString(&event.xkey,NULL,0,&keysym,NULL);
  242.       
  243.       if (keysym == XK_q)
  244.     exit(0);
  245.     }
  246. }
  247.  
  248.  
  249.  
  250. void State::checkFiles()
  251. {
  252.   struct stat pixmapStat;
  253.   stat(pixmapName,&pixmapStat);
  254.  
  255.   struct stat maskStat;
  256.   if (maskSet)
  257.     stat(maskName,&maskStat);
  258.   
  259.   if ((pixmapStat.st_mtime != pixmapTime) ||
  260.       (maskSet && (maskStat.st_mtime != maskTime)))
  261.     {
  262.       pixmapTime = pixmapStat.st_mtime;
  263.       if (maskSet)
  264.     maskTime = maskStat.st_mtime;
  265.       reloadImage();
  266.     }
  267. }
  268.  
  269.  
  270.  
  271. void State::draw()
  272. {
  273.   if (pixmap)
  274.     {
  275.       if (maskSet)
  276.     assert(mask);
  277.  
  278.       XClearWindow(dpy,drawing);
  279.       if (maskSet)
  280.     XSetClipMask(dpy,gc,mask);
  281.       XCopyPlane(dpy,pixmap,drawing,gc,
  282.          0,0,pixmapWidth,pixmapHeight,0,0,1UL);
  283.       if (maskSet)
  284.     XSetClipMask(dpy,gc,None);
  285.     }
  286. }
  287.  
  288.  
  289.  
  290. main (int argc, char **argv)
  291. {
  292.   State state(argc,argv);
  293.  
  294.   while (True) 
  295.     {
  296.       XEvent event;
  297.       if (XCheckMaskEvent(state.getDpy(),
  298.               ExposureMask | KeyPressMask | ButtonPressMask,
  299.               &event))
  300.     {
  301.       switch (event.type) {
  302.       case KeyPress:
  303.         state.checkQuit(event);
  304.         // No "break;" so will reload image.
  305.           
  306.         case ButtonPress:
  307.           state.reloadImage();
  308.         break;
  309.  
  310.       case Expose:
  311.         if (state.canDraw())
  312.           state.draw();
  313.         else
  314.           state.reloadImage();
  315.         break;
  316.         
  317.       default:
  318.         break;
  319.       };
  320.     }
  321.       else
  322.     state.checkFiles();
  323.  
  324.       sleep(TIME_UNIT);
  325.     }
  326. }
  327.